package com.species.web.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SpeciesUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.domain.IntegrationChangeHistory;
import com.ruoyi.system.domain.SmsPrize;
import com.ruoyi.system.domain.SmsPrizeHistory;
import com.ruoyi.system.domain.SmsSpeciesReport;
import com.ruoyi.system.domain.vo.PrizeRedeemVo;
import com.ruoyi.system.domain.vo.ReportSpeciesVo;
import com.ruoyi.system.domain.vo.WxMaLoginForm;
import com.ruoyi.system.service.*;
import com.species.web.service.IUserService;
import com.species.web.wechat.miniapp.config.WxMiniAppConfig;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

/**
 * @author dries
 * @date 2022/3/20
 */
@Slf4j
@Service
public class UserServiceImpl implements IUserService {

    @Resource
    private ISpeciesUserService speciesUserService;
    @Resource
    private ISmsPrizeService prizeService;
    @Resource
    private ISmsSpeciesReportService speciesReportService;
    @Resource
    private ISmsPrizeHistoryService prizeHistoryService;
    @Resource
    private IIntegrationChangeHistoryService integrationChangeHistoryService;

    @Override
    public SpeciesUser wxLogin(WxMaLoginForm vo) {
        // 解析OpenId
        final WxMaService wxMaService = WxMiniAppConfig.getMaService(vo.getAppId());

        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(vo.getCode());
            WxMaUserInfo userInfo = vo.getUserInfo();
            if (ObjectUtil.isNull(userInfo)) {
                // 解密用户信息
                userInfo = wxMaService.getUserService().getUserInfo(session.getSessionKey(), vo.getEncryptedData(), vo.getIv());
            }
            userInfo.setOpenId(session.getOpenid());
            if (session.getUnionid() != null) {
                userInfo.setUnionId(session.getUnionid());
            }
            log.info("微信用户信息=============》{}", userInfo);
            return speciesUserService.loginByWxMiniApp(userInfo);
        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            throw new ServiceException(e.getMessage());
        }
    }

    @Override
    public SpeciesUser getUserInfo(String openId) {
        return speciesUserService.selectSpeciesUserByOpenId(openId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized AjaxResult prizeRedeem(PrizeRedeemVo prizeRedeemVo) {
        // 查询用户信息
        SpeciesUser userInfo = this.getUserInfo(prizeRedeemVo.getOpenId());
        if (ObjectUtil.isNull(userInfo)) {
            return AjaxResult.error("未查询到用户信息");
        }
        // 查询奖品信息
        SmsPrize smsPrize = prizeService.selectSmsPrizeById(Long.valueOf(prizeRedeemVo.getPrizeId()));
        if (ObjectUtil.isNull(smsPrize)) {
            return AjaxResult.error("未查询到奖品信息");
        }
        if (smsPrize.getPrizeCount() <= 0) {
            return AjaxResult.error("您来晚了，奖品已经兑换完了");
        }

        Long integral = userInfo.getIntegral();
        Long prizeIntegral = Long.valueOf(smsPrize.getIntegral());
        if (integral > prizeIntegral) {
            StringBuilder address = new StringBuilder();
            List<String> areas = Arrays.asList(prizeRedeemVo.getArea().split(" "));
            areas.forEach(address::append);
            address.append(prizeRedeemVo.getAddress());
            // 满足兑换条件
            SmsPrizeHistory smsPrizeHistory = new SmsPrizeHistory();
            smsPrizeHistory.setPrizeId(Long.valueOf(prizeRedeemVo.getPrizeId()));
            smsPrizeHistory.setPrizeName(smsPrize.getName());
            smsPrizeHistory.setUserId(userInfo.getOpenId());
            smsPrizeHistory.setCode(IdUtil.fastSimpleUUID());
            smsPrizeHistory.setMobile(prizeRedeemVo.getPhone());
            smsPrizeHistory.setUsername(prizeRedeemVo.getUsername());
            smsPrizeHistory.setAddress(address.toString());
            int i = prizeHistoryService.insertSmsPrizeHistory(smsPrizeHistory);
            if (i == 1) {
                // 更新用户积分
                userInfo.setIntegral(integral - prizeIntegral);
                speciesUserService.updateSpeciesUser(userInfo);

                // 更新奖品数量
                smsPrize.setPrizeCount(smsPrize.getPrizeCount() - 1);
                prizeService.updateSmsPrize(smsPrize);

                // 插入积分记录
                IntegrationChangeHistory integrationChangeHistory = new IntegrationChangeHistory();
                integrationChangeHistory.setMemberId(userInfo.getId());
                integrationChangeHistory.setChangeType("1");
                integrationChangeHistory.setChangeCount(prizeIntegral);
                integrationChangeHistory.setRemark("奖品兑换");
                integrationChangeHistoryService.insertIntegrationChangeHistory(integrationChangeHistory);
                return AjaxResult.success("兑换成功");
            }
            return AjaxResult.success("兑换异常");
        } else {
            return AjaxResult.error("抱歉，你的积分不足");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateSpeciesUser(SpeciesUser speciesUser) {
        return speciesUserService.updateSpeciesUser(speciesUser);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult reportSpecies(ReportSpeciesVo vo) {

        StringBuilder address = new StringBuilder();
        List<String> areas = Arrays.asList(vo.getArea().split(" "));
        areas.forEach(address::append);
        address.append(vo.getAddress());

        SmsSpeciesReport speciesReport = new SmsSpeciesReport();
        speciesReport.setName(vo.getSpeciesName());
        speciesReport.setImages(vo.getUrl());
        speciesReport.setAddress(address.toString());
        speciesReport.setUserId(vo.getOpenId());
        speciesReport.setMobile(vo.getPhone());
        speciesReport.setStatus(0);
        speciesReport.setRemark(vo.getUsername());
        speciesReportService.insertSmsSpeciesReport(speciesReport);

        return AjaxResult.success();
    }


}
